﻿using Blm.Utils.Extensions;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Threading.Tasks;
using VisionCloud.Domain.Common;

namespace VisionCloud.Api.Controllers
{
    /// <summary>
    /// 控制器基类
    /// </summary>
    [ApiController]
    public class ApiBaseController : Controller
    {
        /// <summary>
        /// Token中的用户信息
        /// </summary>
        public OperatorInfo TokenModel { get; set; } = OperatorProvider.Get();

        #region TryCatch方法

        /// <summary>
        /// 包含异常处理的调用
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        [NonAction]
        public async Task<ApiResult> TryCatch(Func<Task> action)
        {
            await action();
            return new ApiResult(AjaxCode.Success);
        }

        /// <summary>
        /// 异常捕获
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="func"></param>
        /// <returns></returns>
        [NonAction]
        public async Task<ApiResult> TryCatch<T>(Func<Task<T>> func)
        {
            var result = await func();
            return new ApiResult(AjaxCode.Success)
            {
                Result = result
            };
        }

        /// <summary>
        /// 异步的异步捕获异常执行执行action
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        [NonAction]
        public async Task<ApiResult> TryCatchAsync(Task action)
        {
            await action;
            return new ApiResult(AjaxCode.Success);
        }

        /// <summary>
        /// 泛型异步捕获异常执行action
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="func"></param>
        /// <returns></returns>
        [NonAction]
        public async Task<ApiResult> TryCatchAsync<T>(Task<T> func)
        {
            var result = await func;
            return new ApiResult(AjaxCode.Success)
            {
                Result = result
            };
        }

        /// <summary>
        /// 异步捕获异常执行，返回ApiResult
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        [NonAction]
        public async Task<ApiResult> TryCatchAsync(Task<ApiResult> func)
        {
            return await func;
        }

        /// <summary>
        /// 泛型异步执行泛型方法，返回泛型结果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="T1"></typeparam>
        /// <param name="func"></param>
        /// <returns></returns>
        [NonAction]
        public async Task<ApiRespBase<T>> TryCatchGenericAsync<T, T1>(Task<T1> func) where T1 : ApiRespBase<T>
        {
            try
            {
                return await func;
            }
            catch (OperationException e)
            {
                //业务错误直接返回错误信息
                return new ApiRespBase<T> { Code = AjaxCode.Error.ToInt32(), Message = e.Message };
            }
            catch (Exception e)
            {
#if DEBUG
                return new ApiRespBase<T> { Code = AjaxCode.Error.ToInt32(), Message = e.Message };
#else
                return new ApiRespBase<T> { Code = (int)AjaxCode.Error, Message = "服务器内部错误" };
#endif
            }
        }

        #endregion TryCatch方法

        #region 获取接口的唯一名称

        /// <summary>
        /// 获取接口的唯一名称
        /// </summary>
        /// <param name="parms">确定唯一名称的</param>
        /// <returns></returns>
        [NonAction]
        public string GetOpenApiName(params object[] parms)
        {
            if (parms != null && parms.Length > 0)
            {
                return ControllerContext.HttpContext.Request.Path
                       + ControllerContext.HttpContext.Request.QueryString
                       + string.Join(',', parms);
            }
            return ControllerContext.HttpContext.Request.Path + ControllerContext.HttpContext.Request.QueryString;
        }

        #endregion 获取接口的唯一名称
    }
}